package jp.co.nes.awssupport.common.utility;

import java.io.File;
import java.io.InputStream;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.PutObjectResult;
import com.amazonaws.services.s3.model.S3Object;

/**
 * s3ヘルパーです。<br>
 * s3に関する機能を提供します。
 */
public class AwsS3Helper extends AwsHelperBase {

    /** クライアント */
    private AmazonS3 client;

    /**
     * デフォルトコンストラクタです。
     */
    public AwsS3Helper() {
    }

    /**
     * アクセスキー、シークレットキーを引数にもつコンストラクタです。
     *
     * @param accessKey アクセスキー
     * @param secretKey シークレットキー
     */
    public AwsS3Helper(String accessKey, String secretKey) {
        super(accessKey, secretKey);
    }

    /*
     * (非 Javadoc)
     * @see jp.co.nes.awssupport.common.utility.AwsHelperBase#init(com.amazonaws.regions.Regions, com.amazonaws.auth.AWSCredentials, com.amazonaws.ClientConfiguration)
     */
    @Override
    protected void init(Regions regions, AWSCredentials credentials, ClientConfiguration config) {
        boolean isLocalTest = Boolean.valueOf(PropertiesUtil.getProperty("LocalTest", "false"));
        if (!isLocalTest) {
            if (credentials == null) {
                if (config == null) {
                    client = AmazonS3ClientBuilder.standard()
                            .withRegion(regions)
                            .build();
                } else {
                    client = AmazonS3ClientBuilder.standard()
                            .withRegion(regions)
                            .withClientConfiguration(config)
                            .build();
                }
            } else {
                if (config == null) {
                    client = AmazonS3ClientBuilder.standard()
                            .withRegion(regions)
                            .withCredentials(new AWSStaticCredentialsProvider(credentials))
                            .withClientConfiguration(new ClientConfiguration())
                            .build();
                } else {
                    client = AmazonS3ClientBuilder.standard()
                            .withRegion(regions)
                            .withCredentials(new AWSStaticCredentialsProvider(credentials))
                            .withClientConfiguration(config)
                            .build();
                }
            }
        }
    }

    /**
     * s3オブジェクトを返却します。
     *
     * @param bucketName バケット名
     * @param objectKey オブジェクトキー
     * @return s3オブジェクト
     */
    public S3Object getObject(String bucketName, String objectKey) {
        GetObjectRequest request = new GetObjectRequest(bucketName, objectKey);
        return client.getObject(request);
    }

    /**
     * 指定されたプリフィックスでフィルタリングしたバケット内の一覧を返却します。
     *
     * @param bucketName バケット名
     * @param prefix プリフィックス
     * @return 一覧
     */
    public ObjectListing listObjects(String bucketName, String prefix) {
        return client.listObjects(bucketName, prefix);
    }

    /**
     * バケット内の一覧を返却します。
     *
     * @param bucketName バケット名
     * @return 一覧
     */
    public ObjectListing listObjects(String bucketName) {
        return client.listObjects(bucketName);
    }

    /**
     * 指定されたバケット名とキーに対応するオブジェクトを削除します。
     *
     * @param bucketName バケット名
     * @param key キー
     */
    public void deleteObject(String bucketName, String key) {
        client.deleteObject(bucketName, key);
    }

    /**
     * s3にファイルを保存します。
     *
     * @param bucketName バケット名
     * @param objectKey オブジェクトキー
     * @param inputStream 入力ストリーム
     * @param encoding エンコーディング
     * @param contentLength コンテンツサイズ
     * @param contentType コンテンツタイプ
     * @return 保存結果
     */
    public PutObjectResult putObject(String bucketName, String objectKey, InputStream inputStream, String encoding,
            long contentLength, String contentType) {
        ObjectMetadata metadata = new ObjectMetadata();
        if (encoding != null) {
            metadata.setContentEncoding(encoding);
        }
        if (contentLength != 0) {
            metadata.setContentLength(contentLength);
        }
        if (contentType != null) {
            metadata.setContentType(contentType);
        }

        PutObjectRequest request = new PutObjectRequest(bucketName, objectKey, inputStream, metadata);

        return client.putObject(request);
    }

    /**
     * s3にファイルを保存します。
     *
     * @param bucketName バケット名
     * @param objectKey オブジェクトキー
     * @param file ファイル
     * @return 保存結果
     */
    public PutObjectResult putObject(String bucketName, String objectKey, File file) {
        PutObjectRequest request = new PutObjectRequest(bucketName, objectKey, file);
        return client.putObject(request);
    }
}
